// $Id: niohttp.h 62 2011-04-23 08:56:48Z cedric.shih@gmail.com $
/*
 * Copyright (C) 2010 Cedric Shih <cedric.shih@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef NIOHTTP_H_
#define NIOHTTP_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/queue.h>
#include <sys/types.h>
#include <errno.h>

#include <nio.h>

const char *niohttp_get_version(void);

enum niohttp_errno {
	NIOHTTP_EOK = 0, /**< Success. */
	NIOHTTP_EINVAL = EINVAL, /**< Invalid argument(s). */
	NIOHTTP_ENOMEM = ENOMEM, /**< Out of memory. */
	NIOHTTP_ENOENT = ENOENT, /**< Session not pending. */
	NIOHTTP_EEXIST = EEXIST, /**< Session pending. */
	NIOHTTP_EAGAIN = EAGAIN, /**< Try again later. */
	NIOHTTP_EINPROGRESS = EINPROGRESS, /**< Operation in progress. */
	NIOHTTP_EIO = EIO, /**< Buffering error. */
	NIOHTTP_EUNKNOWN = 0x8000, /**< Unknown error. */
	NIOHTTP_EBUFFER, /**< Buffering error. */
};

const char *niohttp_strerror(enum niohttp_errno err);

/**
 * @brief Set logger function.
 *
 * @param cb - logger function
 * @param buffer - buffer for message formatting
 * @param len - size of buffer
 * @see niohttp_logger_cb
 */
void niohttp_logger_set(niologger_cb cb, void *arg);

struct niohttp_header {
	const char *name;
	const char *value;
	TAILQ_ENTRY(niohttp_header) next;
};

TAILQ_HEAD(niohttp_header_list, niohttp_header);

struct niohttp_request;

struct niohttp_response;

struct niobuffer;

struct niohttp_message {
	struct niohttp_request *request;
	struct niohttp_response *response;
	struct niobuffer *content;
};

typedef void (*niohttp_request_cb)(struct niohttp_request *req,
		struct niohttp_response *resp, void *cbarg);

struct niohttp_request *niohttp_request_new(void);

void niohttp_request_free(struct niohttp_request *req);

const char *niohttp_request_protocol(struct niohttp_request *req);

const char *niohttp_request_version(struct niohttp_request *req);

int niohttp_request_major_version(struct niohttp_request *req);

int niohttp_request_minor_version(struct niohttp_request *req);

const char *niohttp_request_method(struct niohttp_request *req);

const char *niohttp_request_uri(struct niohttp_request *req);

const char *niohttp_request_header(struct niohttp_request *req,
		const char *name);

struct niohttp_header_list *niohttp_request_headers(
		struct niohttp_request *req);

struct niohttp_response *niohttp_request_create_response(
		struct niohttp_request *req, int code, const char *reason);

int niohttp_request_set_protocol(struct niohttp_request *req,
		const char *protocol);

int niohttp_request_set_version(struct niohttp_request *req,
		const char *version);

int niohttp_request_set_method(struct niohttp_request *req,
		const char *method);

int niohttp_request_set_uri(struct niohttp_request *req,
		const char *uri);

int niohttp_request_set_header(struct niohttp_request *req,
		const char *name, const char *value);

int niohttp_request_remove_header(struct niohttp_request *req,
		const char *name);

int niohttp_request_clear_headers(struct niohttp_request *req);

struct niohttp_response *niohttp_response_new(void);

void niohttp_response_free(struct niohttp_response *resp);

const char *niohttp_response_protocol(struct niohttp_response *resp);

const char *niohttp_response_version(struct niohttp_response *resp);

int niohttp_response_major_version(struct niohttp_response *resp);

int niohttp_response_minor_version(struct niohttp_response *resp);

int niohttp_response_code(struct niohttp_response *resp);

const char *niohttp_response_reason(struct niohttp_response *resp);

const char *niohttp_response_header(struct niohttp_response *resp,
		const char *name);

struct niohttp_header_list *niohttp_response_list_headers(
		struct niohttp_response *resp);

int niohttp_response_set_protocol(struct niohttp_response *resp,
		const char *protocol);

int niohttp_response_set_version(struct niohttp_response *resp,
		const char *version);

int niohttp_response_set_status(struct niohttp_response *resp,
		int code, const char *reason);

int niohttp_response_set_code(struct niohttp_response *resp, int code);

int niohttp_response_set_reason(struct niohttp_response *resp,
		const char *reason);

int niohttp_response_set_header(struct niohttp_response *resp,
		const char *name, const char *value);

int niohttp_response_remove_header(struct niohttp_response *resp,
		const char *name);

int niohttp_response_clear_headers(struct niohttp_response *resp);

struct niobuffer;

struct nioreactor;

struct niohttp_session;

struct niosocket;

typedef void (*niohttp_session_tunnel_cb)(struct niohttp_session *session,
		struct niosocket *socket, void *cbarg);

struct niohttp_session *niohttp_session_new(
		struct nioreactor *reactor, struct niobuffer *buffer,
		struct niosocket *socket);

void niohttp_session_free(struct niohttp_session *session);

int niohttp_session_submit(struct niohttp_session *session,
		struct niohttp_request *req, struct niobuffer *content,
		niohttp_request_cb cb, void *cbarg);

int niohttp_session_pending(struct niohttp_session *session);

int niohttp_session_cancel(struct niohttp_session *session);

int niohttp_session_writable(struct niohttp_session *session,
		niohttp_session_tunnel_cb cb, void *cbarg);

int niohttp_session_readable(struct niohttp_session *session,
		niohttp_session_tunnel_cb cb, void *cbarg);

struct niohttp_headers *niohttp_headers_new(void);

void niohttp_headers_free(struct niohttp_headers *headers);

void niohttp_headers_clear(struct niohttp_headers *headers);

struct niohttp_header_list *niohttp_headers_list(
		struct niohttp_headers *headers);

struct niohttp_headers *niohttp_headers_clone(
		struct niohttp_headers *source, int strdup);

int niohttp_headers_load(struct niohttp_headers *headers,
		struct niohttp_headers *source);

int niohttp_headers_set(struct niohttp_headers *headers,
		const char *name, const char *value);

const char *niohttp_headers_get(struct niohttp_headers *headers,
		const char *name);

int niohttp_headers_remove(struct niohttp_headers *headers,
		const char *name);

size_t niohttp_headers_size(struct niohttp_headers *headers);

#ifdef __cplusplus
}
#endif

#endif /* NIOHTTP_H_ */
